package edu.pdx.cs.cs542s07.minichess;

import java.util.HashMap;

class ScoreFactory {
	
	static final int OPPONENT_WINS 	= -1000;
	static final int YOU_WIN 	= 1000;
	static final int PAWN_SCORE 	= 10;
	static final int BISHOP_SCORE 	= 20;
	static final int ROOK_SCORE 	= 30;
	static final int KNIGHT_SCORE 	= 30;
	static final int QUEEN_SCORE 	= 100;
	static final int PAWN_ROW_SCORE = 1;
	static final int IMPOSSIBLE_SCORE = (YOU_WIN*2) + 1;

	static TransitionTable ttable = new TransitionTable();
	
	/**
	 * Talies up the score for this board for the player about to move
	 * @param board the board state after the last move
	 * @return the total score of all the pieces. 
	 */
	private int scoreBoard(Board board) {
		
		int score = ttable.get(board);
		//int score;
		
		if (score != ScoreFactory.IMPOSSIBLE_SCORE) {
			return score;
		}
		
		// if we get an impossible score, we need to calculate it.
		int blackScore = scoreBoardHelper(board.getBlackPieces());
		int whiteScore = scoreBoardHelper(board.getWhitePieces());
		
		if (blackScore == OPPONENT_WINS) 
			score = OPPONENT_WINS;
		else if (whiteScore == OPPONENT_WINS)
			score = YOU_WIN;
		else
			score = ((blackScore-whiteScore));

		if (board.getTurn() == Color.BLACK) {
			ttable.set(board, score);
			return score;
		} else /* white */ {
			ttable.set(board, -score);
			return -score;
		}
		
	}
	
	/**
	 * Tallies up the score total for the pieces on the board. If the king is absent, the score is OPPONENT_WINS.
	 * @param pieces
	 * @return
	 */
	private int scoreBoardHelper(HashMap<Piece, Square> pieces) {
		int score = 0;
		boolean hasKing = false;
		for(Piece piece:pieces.keySet()) {
			if (piece.type == PieceType.KING) {
				hasKing = true;
			} 
			score += scorePiece(piece, pieces.get(piece));
		}
		if (!hasKing) {
			return OPPONENT_WINS;
		} else {
			return score;
		}
			
	}
	
	static int scorePiece(Piece piece, Square position){
		
		int score = 0;
		
		if (piece.type == PieceType.PAWN) {
				score += PAWN_SCORE;
				int row = position.row;
				if (piece.color == Color.WHITE) {
					score += row * PAWN_ROW_SCORE;
				} else {
					score += ((Board.NUMBER_OF_ROWS-1) - row) * PAWN_ROW_SCORE;
				}
		} else if (piece.type == PieceType.QUEEN) {
			score += QUEEN_SCORE;
		} else if (piece.type == PieceType.ROOK) {
			score += ROOK_SCORE;
		} else if (piece.type == PieceType.BISHOP) {
			score += BISHOP_SCORE;
		} else if (piece.type == PieceType.KNIGHT) {
			score += KNIGHT_SCORE;
		} else if (piece.type == PieceType.KING) {
			score += YOU_WIN;
		}
		
		return score;
		
	}
	
}
